//
//  AVAudio.m
//  YouYiKuProject
//
//  Created by xue on 2019/1/10.
//  Copyright © 2019年 xuezi. All rights reserved.
//

#import "AVAudio.h"
#import <AVFoundation/AVFoundation.h>
#import "lame.h"


#define DEFINE_SHARED_INSTANCE_USING_BLOCK(block) \
static dispatch_once_t pred = 0; \
static id _sharedObject = nil; \
dispatch_once(&pred, ^{ \
_sharedObject = block(); \
}); \
return _sharedObject; \

@interface AVAudio()<AVAudioRecorderDelegate>
/** 录音对象 */
@property (nonatomic, strong) AVAudioRecorder *recoder;
/** 录音文件路径 */
@property (nonatomic, strong) NSString * recordeFilePath;
/** 音频文件地址 */
@property (nonatomic, strong) NSURL * url;
/**
 转换的Mp3文件地址
 */
@property (nonatomic,strong) NSURL * mp3Url;

/** 音频播放器 */
@property (nonatomic,strong) AVAudioPlayer * player;


@end
@implementation AVAudio
+ (AVAudio *)sharedInstance{
    
    DEFINE_SHARED_INSTANCE_USING_BLOCK(^{
        
        return [[self alloc] init];
    });
}

- (id)init{
    
    self = [super init];
    if (self) {
//        [self initRecorder];
    }
    return self;
}

-(void)startRecorder{
    
    if([self.recoder prepareToRecord]){
        //开始
        [self.recoder record];
        NSLog(@"开始录音");
    }
}

-(void)stopRecorder{
    
    
    //获取当前录音时长
    float voiceSize = self.recoder.currentTime;
    
    NSURL *url =self.recoder.url;
    NSLog(@"录音时长 = %f  %@",voiceSize, self.recoder);
    //停止录音
    [self.recoder stop];
    
    [self convertToMp3];
    
}
- (void)playSound{
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    [audioSession setActive:YES error:nil];
    NSError * error = nil;
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:_mp3Url error:&error];
    [self.player play];
}

- (AVAudioRecorder *)recoder
{
    if (!_recoder) {
        
        //存放录音文件的地址
        NSString * path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSString * filePath = [path stringByAppendingPathComponent:@"123.caf"];
        self.recordeFilePath = filePath;
        NSURL * url = [NSURL fileURLWithPath:filePath];
        self.url = url;
        
        
        //录音设置
        NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];
        //设置录音格式
        [recordSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey: AVFormatIDKey];
        //采样率 采样率必须要设为11025才能使转化成mp3格式后不会失真
        [recordSettings setValue :[NSNumber numberWithFloat:11025.0] forKey: AVSampleRateKey];//44100.0
        //通道数要转换成MP3格式必须为双通道
        [recordSettings setValue :[NSNumber numberWithInt:2] forKey: AVNumberOfChannelsKey];
        
        //音频质量,采样质量
        [recordSettings setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
        
        //创建录音对象
        _recoder = [[AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:nil];
        
        [_recoder prepareToRecord];
    }
    
    return _recoder;
}
- (void)convertToMp3
{
    NSString *strUrl = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *mp3FilePath = [strUrl stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",[AVAudio GetCurrentTimeString]]];
    
    @try {
        int read,write;
        //只读方式打开被转换音频文件
        FILE *pcm = fopen([self.recordeFilePath cStringUsingEncoding:1], "rb");
        fseek(pcm, 4 * 1024, SEEK_CUR);//删除头，否则在前一秒钟会有杂音
        //只写方式打开生成的MP3文件
        FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb");
        
        const int PCM_SIZE = 8192;
        const int MP3_SIZE = 8192;
        short int pcm_buffer[PCM_SIZE * 2];
        unsigned char mp3_buffer[MP3_SIZE];
        //这里要注意，lame的配置要跟AVAudioRecorder的配置一致，否则会造成转换不成功
        lame_t lame = lame_init();
        lame_set_in_samplerate(lame, 11025.0);//采样率
        lame_set_VBR(lame, vbr_default);
        lame_init_params(lame);
        
        do {
            
            //以二进制形式读取文件中的数据
            read = (int)fread(pcm_buffer, 2 * sizeof(short int), PCM_SIZE, pcm);
            if (read == 0)
                write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            else
                write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
            
            //二进制形式写数据到文件中  mp3_buffer：数据输出到文件的缓冲区首地址  write：一个数据块的字节数  1:指定一次输出数据块的个数   mp3:文件指针
            fwrite(mp3_buffer, write, 1, mp3);
            
        } while (read != 0);
        
        lame_close(lame);
        fclose(mp3);
        fclose(pcm);
        
    } @catch (NSException *exception) {
        NSLog(@"%@",[exception description]);
    } @finally {
        NSLog(@"MP3生成成功!!!");
        strUrl = mp3FilePath;
//        NSLog(@"MP3生成成功: %@",strUrl);
        _mp3Url =[NSURL fileURLWithPath:strUrl];
//        NSLog(@"dfdf=%@",self.recoder.url);
//        float voiceSize = self.recoder.currentTime;
//        NSLog(@"voiceSize=%f",voiceSize);
//        NSLog(@"文件格式===%@",[self getMIMETypeWithCAPIAtFilePath:mp3FilePath]);
        [self uploadRecord:_mp3Url];
        
    }
}

#pragma mark--音频上传接口
/**
 音频上传
 
 @param url url
 */
- (void)uploadRecord:(NSURL *)url{
    //    上传data
    
    NSData *data = [NSData dataWithContentsOfURL:url];
    
    [Utils POST:Url_AppUploadVoice parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        //上传的参数(上传图片，以文件流的格式)

        
        NSDateFormatter*formatter=[[NSDateFormatter alloc]init];
        formatter.dateFormat = @"yyyy-MM-dd-HH:mm:ss";
        NSString *str = [formatter stringFromDate:[NSDate date]];
        [formData appendPartWithFileData:data name:@"file" fileName:[NSString stringWithFormat:@"%@.mp3",str] mimeType:@"audio/mpeg"];
        
        
    } success:^(id responseObject) {
        if (responseObject) {
            
//            NSString *myerror =responseObject[@"myerror"];
            
            if ([self.delegate respondsToSelector:@selector(aVAudio:aVAudioInfo:)]) {
                [self.delegate aVAudio:self aVAudioInfo:responseObject];
            }
        }
        
    } failure:^(NSError *error) {
        
    }];
    
    
}
///生成当前时间字符串
+(NSString*)GetCurrentTimeString{
    
    NSDateFormatter *dateformat = [[NSDateFormatter  alloc]init];
    
    [dateformat setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
    
    return [dateformat stringFromDate:[NSDate date]];
}
//调用C语言的API来获得文件的MIMEType ，只能获取本地文件哦，无法获取网络请求来的文件
-(NSString *)getMIMETypeWithCAPIAtFilePath:(NSString *)path
{
    if (![[[NSFileManager alloc] init] fileExistsAtPath:path]) {
        return nil;
    }
    
    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);
    CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
    CFRelease(UTI);
    if (!MIMEType) {
        return @"application/octet-stream";
    }
    return (__bridge NSString *)(MIMEType);
}


@end
